package com.vegetable.modules.service.sys.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.constant.CommonConstant;
import com.vegetable.common.utils.Constant;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.common.utils.Query;
import com.vegetable.modules.entity.baseData.InvoiceInfo;
import com.vegetable.modules.entity.sys.SysUserEntity;
import com.vegetable.modules.exception.RRException;
import com.vegetable.modules.form.sys.UserQueryForm;
import com.vegetable.modules.mapper.sys.SysRoleDao;
import com.vegetable.modules.mapper.sys.SysUserDao;
import com.vegetable.modules.mapper.wx.SysUserDepartmentDao;
import com.vegetable.modules.service.sys.SysUserRoleService;
import com.vegetable.modules.service.sys.SysUserService;
import com.vegetable.modules.vo.sys.SysUserVO;
import com.vegetable.modules.entity.wx.WxDepartment;
import com.vegetable.modules.entity.wx.SysUserDepartment;
import com.vegetable.modules.service.wx.WxDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Slf4j
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	@Resource
	private SysUserRoleService sysUserRoleService;
	@Resource
	private SysRoleDao sysRoleDao;
	@Resource
	private WxDepartmentService wxDepartmentService;
	@Resource
	private SysUserDepartmentDao sysUserDepartmentDao;


	public PageUtils queryPage(Map<String, Object> params) {
		String username = (String)params.get("username");
		Long createUserId = (Long)params.get("createUserId");
		Integer status = (Integer) params.get("status");
		List<Long> sysUserIds = (List<Long>) params.get("userIds");

		QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
		queryWrapper.like(StringUtils.isNotBlank(username),"username", username)
				.eq(createUserId != null,"create_user_id", createUserId)
				.eq(Objects.nonNull(status),"status", status);
		
		// 如果指定了系统用户ID列表，则添加IN查询条件
		if (sysUserIds != null && !sysUserIds.isEmpty()) {
			queryWrapper.in("user_id", sysUserIds);
		}
		IPage<SysUserEntity> iPage = new Page<>((Long) params.get("page"), (Long) params.get("limit"));
		IPage<SysUserEntity> page = this.page(iPage, queryWrapper);

		return new PageUtils(page);
	}
	
	/**
	 * 使用UserQueryForm对象作为参数的分页查询方法
	 * @param form 查询参数
	 * @return 用户分页列表
	 */
	public PageUtils queryPage(UserQueryForm form) {
		// 如果指定了部门ID，则先查询该部门下的所有用户ID
		List<Long> sysUserIds = null;
		if (form.getDepartmentId() != null) {
			// 使用新的方法获取部门下的用户
			List<SysUserDepartment> departmentUsers = getDepartmentUsers(form.getDepartmentId());
			sysUserIds = departmentUsers.stream()
					.map(SysUserDepartment::getUserId)
					.collect(Collectors.toList());
			
			// 如果该部门下没有用户，则直接返回空结果
			if (sysUserIds.isEmpty()) {
				Map<String, Object> emptyParams = new HashMap<>();
				emptyParams.put("page", form.getPage());
				emptyParams.put("limit", form.getLimit());
				IPage<SysUserEntity> emptyPage = new Page<>();
				emptyPage.setRecords(Collections.emptyList());
				emptyPage.setCurrent(form.getPage());
				emptyPage.setSize(form.getLimit());
				emptyPage.setTotal(0);
				return new PageUtils(emptyPage);
			}
		}
		
		Map<String, Object> params = new HashMap<>();
		if (form.getUsername() != null) {
			params.put("username", form.getUsername());
		}
		if (form.getCreateUserId() != null) {
			params.put("createUserId", form.getCreateUserId());
		}
		if (form.getStatus() != null) {
			params.put("status", form.getStatus());
		}
		// 如果指定了部门ID，添加用户ID列表条件
		if (sysUserIds != null) {
			params.put("userIds", sysUserIds);
		}
		params.put("page", form.getPage());
		params.put("limit", form.getLimit());
		params.put("sort", form.getSort());
		params.put("order", form.getOrder());

		return queryPage(params);
	}

	@Override
	public IPage<SysUserVO> queryPageWithDepartments(UserQueryForm form) {
		// 如果指定了部门ID，则先查询该部门下的所有用户ID
		List<Long> sysUserIds = null;
		if (form.getDepartmentId() != null) {
			// 使用新的方法获取部门下的用户
			List<SysUserDepartment> departmentUsers = getDepartmentUsers(form.getDepartmentId());
			sysUserIds = departmentUsers.stream()
					.map(SysUserDepartment::getUserId)
					.collect(Collectors.toList());
			
			// 如果该部门下没有用户，则直接返回空结果
			if (sysUserIds.isEmpty()) {
				IPage<SysUserVO> emptyPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
				emptyPage.setRecords(new ArrayList<>());
				emptyPage.setCurrent(form.getPage());
				emptyPage.setSize(form.getLimit());
				emptyPage.setTotal(0);
				return emptyPage;
			}
		}
		
		// 构造查询参数Map
		Map<String, Object> params = new HashMap<>();
		if (form.getUsername() != null) {
			params.put("username", form.getUsername());
		}
		if (form.getCreateUserId() != null) {
			params.put("createUserId", form.getCreateUserId());
		}
		if (form.getStatus() != null) {
			params.put("status", form.getStatus());
		}
		// 如果指定了部门ID，添加用户ID列表条件
		if (sysUserIds != null) {
			params.put("userIds", sysUserIds);
		}
		params.put("page", form.getPage());
		params.put("limit", form.getLimit());
		
		// 先查询用户分页列表
		PageUtils userPage = this.queryPage(params);
		
		// 转换为包含部门信息的用户列表
		List<SysUserEntity> userList = (List<SysUserEntity>) userPage.getList();
		List<SysUserVO> userVOList = new ArrayList<>();
		
		for (SysUserEntity user : userList) {
			// 隐藏关键信息
			user.setPassword(null);
			user.setSalt(null);
			user.setOpenId(null);

			SysUserVO userVO = new SysUserVO();
			userVO.setUser(user);
			
			// 获取用户所属部门
			List<WxDepartment> departments = wxDepartmentService.getSysUserDepartments(user.getUserId());
			userVO.setDepartments(departments);
			
			userVOList.add(userVO);
		}
		
		// 构造新的IPage对象
		IPage<SysUserVO> resultPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
		resultPage.setRecords(userVOList);
		resultPage.setCurrent(userPage.getCurrPage());
		resultPage.setSize(userPage.getPageSize());
		resultPage.setTotal(userPage.getTotalCount());
		
		return resultPage;
	}

	/**
	 * 根据部门ID获取该部门下的所有用户
	 * @param departmentId 部门ID
	 * @return 用户部门关联列表
	 */
	private List<SysUserDepartment> getDepartmentUsers(Long departmentId) {
		QueryWrapper<SysUserDepartment> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("department_id", departmentId);
		return sysUserDepartmentDao.selectList(queryWrapper);
	}

	@Override
	public List<String> queryAllPerms(Long userId) {
		return baseMapper.queryAllPerms(userId);
	}

	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return baseMapper.queryAllMenuId(userId);
	}

	@Override
	public SysUserEntity queryByUserName(String username) {
		return baseMapper.queryByUserName(username);
	}

	@Override
	public SysUserEntity queryByOpenId(String openId) {
		return baseMapper.queryByOpenId(openId);
	}

	@Override
	public SysUserEntity queryByMobile(String mobile) {
		return baseMapper.queryByMobile(mobile);
	}

	@Override
	@Transactional
	public void saveUser(SysUserEntity user) {
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
//		user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
		user.setPassword(CommonConstant.DEFAULT_PASSWORD);
		user.setSalt(salt);
		this.save(user);
		
		//检查角色是否越权
//		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void update(SysUserEntity user) {
		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		}else{
//			user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
			user.setPassword(user.getPassword());
		}
		this.updateById(user);
		
		//检查角色是否越权
//		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUserEntity userEntity = new SysUserEntity();
		userEntity.setPassword(newPassword);
		return this.update(userEntity,
				new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
	}

	@Override
	public void createVisitor(String mobile, String openId) {
		SysUserEntity visitor = new SysUserEntity();
		visitor.setUsername("游客#" + System.currentTimeMillis());
		visitor.setMobile(mobile);
		visitor.setOpenId(openId);
		visitor.setStatus(1);
		String salt = RandomStringUtils.randomAlphanumeric(20);
		visitor.setPassword(CommonConstant.DEFAULT_PASSWORD);
		visitor.setSalt(salt);
		visitor.setUserType(1);
		this.save(visitor);
		log.info("根据mobile：{} openId：{}创建游客账号", mobile, openId);
	}

	/**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUserEntity user){
		if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
			return;
		}
		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		if(user.getCreateUserId() == Constant.SUPER_ADMIN){
			return ;
		}
		
		//查询用户创建的角色列表
		List<Long> roleIdList = sysRoleDao.queryRoleIdList(user.getCreateUserId());

		//判断是否越权
		if(!roleIdList.containsAll(user.getRoleIdList())){
			throw new RRException("新增用户所选角色，不是本人创建");
		}
	}
}